/**
* Copyright 2009 Maxim Cassian Porges
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*     http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package loom.util
{
	import loom.abc.LNamespace;
	import loom.abc.enum.NamespaceKind;
	
	/**
	 * Utility class offering assertions to be used within the test suite and the Loom project code.
	 */
	public class Assertions
	{
		/**
		 * Given two arrays, asserts that the lengths and contents are identical. Does not care about the order
		 * of items within the arrays, only that the contents all match.
		 * 
		 * <p>
		 * This is a Loom-specific utility and has a few hacks in it, so don't get excited about using it
		 * for general array comparison. For example, even though private namespaces must match as object
		 * references in the AVM2 spec, this method is forgiving in this regard in order to allow array
		 * contents to be checked for semantic equivalence.  
		 * </p>
		 * 
		 * @param firstArray  The first array for the comparison
		 * @param secondArray The secon array to compare <code>firstArray</code> against
		 * @return    <code>true</code> if both arrays match, <code>false</code> otherwise. 
		 */
		public static function assertArrayContentsEqual(firstArray : Array, secondArray : Array) : Boolean
		{
			if (firstArray.length != secondArray.length)
			{
				throw new Error("Array lengths (" + firstArray.length + "," + secondArray.length + ") do not match");
			}
			
			var contentsMatch : Boolean = firstArray.every(
                function(item : Object, index : int, array : Array) : Boolean
                {
                    var matchFound : Boolean = false;
                    for each (var current : Object in secondArray)
                    {
                    	if (current.hasOwnProperty("equals"))
                    	{
	                        if (current.equals(item))
	                        {
	                            matchFound = true;
	                            break;
	                        }
	                        else
	                        {
		                        // Loom-specific exception for private LNamespaces. Allow value equality so that
		                        // sample LNamespaces can be provided for comparison in tests  
		                        if (current is LNamespace)
		                        {
		                        	if (LNamespace(current).kind == NamespaceKind.PRIVATE_NAMESPACE)
		                        	{
		                        		if (LNamespace(current).name == item.name)
		                        		{
		                        			matchFound = true;
	                                        break;
		                        		}
		                        	}
		                        }
	                        }	
                        }
                        else
                        {
                        	if (current == item)
                        	{
                        	   matchFound = true;
                        	   break;
                        	}
                        }
                    }
                    
                    return matchFound;
                }
            );
            
            if (!contentsMatch)
            {
            	throw new Error("Array contents to do not match.");
            }
            
            return true;
		}
	}
}